﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Xml;
using System.IO;

namespace XmlManipulate
{
    public class ObjectToXML
    {
        public static XmlWriterSettings getXmlSettings(Boolean indent, String indentChars, String encoding)
        {
            XmlWriterSettings set = new XmlWriterSettings();
            set.Indent = indent;
            set.IndentChars = (indentChars);
            set.Encoding = System.Text.Encoding.GetEncoding(encoding);
            return set;
        }

        /// <summary>
        /// Gera XML da estrutura de um objeto no formato:
        /// <ObjectType>
        ///     <PropertyName>Value</PropertyName>
        /// </ObjectType>
        /// </summary>
        /// <param name="obj"></param>
        public static void gravarXML(Object obj, String url) {   

            PropertyInfo[] properties = obj.GetType().GetProperties();
            MethodInfo[] methods = obj.GetType().GetMethods();

            XmlWriter writeObject = XmlWriter.Create(url + obj.GetType().ToString() + ".xml",
                getXmlSettings(true, "\t", "UTF-8"));
            
            writeObject.WriteStartElement(obj.GetType().ToString());

            //percorre as properties e monta estrutura:
            //<PropertyName>Value</PropertyName>
            foreach (PropertyInfo prop in properties) {
                writeObject.WriteStartElement("Atributos");
                writeObject.WriteElementString(prop.Name, prop.GetValue(obj, null).ToString());
                writeObject.WriteEndElement();
            }

            //percorre as properties e monta estrutura:
            //<Nome>Value</Nome>
            //<TipoRetorno>Value</TipoRetorno>
            foreach (MethodInfo meth in methods)
            {
                writeObject.WriteStartElement("Metodos");
                writeObject.WriteElementString("Nome", meth.Name);
                writeObject.WriteElementString("TipoRetorno", meth.ReturnType.ToString());

                writeObject.WriteEndElement();
            }

            writeObject.WriteEndElement();
            writeObject.Flush();

            XmlDocument doc = new XmlDocument();
            doc.Save(writeObject);
            
        }

        public static void gravarXMLAtributos(Object obj, String url)
        {

            PropertyInfo[] properties = obj.GetType().GetProperties();
            MethodInfo[] methods = obj.GetType().GetMethods();

            XmlWriter writeObject = XmlWriter.Create(url + obj.GetType().ToString() + ".xml",
                getXmlSettings(true, "\t", "UTF-8"));

            writeObject.WriteStartElement(obj.GetType().ToString());
            writeObject.WriteStartElement("Atributos");
            //percorre as properties e monta estrutura:
            //<PropertyName>Value</PropertyName>
            foreach (PropertyInfo prop in properties)
            {
                writeObject.WriteElementString(prop.Name, prop.GetValue(obj, null).ToString());
            }
            writeObject.WriteEndElement();

            writeObject.WriteEndElement();
            writeObject.Flush();

            XmlDocument doc = new XmlDocument();
            doc.Save(writeObject);

        }

        public static void gravarListXML<T>(List<T> objList, String url)
        {
            XmlWriter writeObject = XmlWriter.Create(url + typeof(T) + "List.xml",
                getXmlSettings(true, "\t", "UTF-8"));

            writeObject.WriteStartElement(typeof(T) + "List");

            foreach (Object obj in objList)
            {
                PropertyInfo[] properties = obj.GetType().GetProperties();

                writeObject.WriteStartElement(obj.GetType().ToString());

                //percorre as properties e monta estrutura:
                //<PropertyName>Value</PropertyName>
                foreach (PropertyInfo prop in properties)
                {
                    writeObject.WriteStartElement("Atributos");
                    writeObject.WriteElementString(prop.Name, prop.GetValue(obj, null).ToString());
                    writeObject.WriteEndElement();
                }

                writeObject.WriteEndElement();
            }

            writeObject.WriteEndElement();
            writeObject.Flush();
            XmlDocument doc = new XmlDocument();

            doc.Save(writeObject);
        }

        //método incompleto
        public static void appendXML(Object obj, String filePath)
        {
            PropertyInfo[] properties = obj.GetType().GetProperties();

            XmlDocument doc = new XmlDocument();

            try
            {
                doc.Load(filePath);
            }
            catch (FileNotFoundException)
            {
                // TODO : tratar exceções
            }
            catch (DirectoryNotFoundException)
            {
                // TODO : tratar exceções
            }

            XmlElement raiz = doc.DocumentElement;

        }
    }
}
